import { Layout } from "@/components/layout/layout";
import withAuth, { getServerSideProps } from "@/hoc/withAuth";
import { useHttp } from "@/hooks";
import useMounted from "@/hooks/useMounted";
import type { NextPage, GetServerSidePropsContext } from "next";
import { useRouter } from "next/router";
import { useEffect, useRef, useState } from "react";
import React from "react";
import {
  Table,
  TableHeader,
  TableColumn,
  TableBody,
  TableRow,
  TableCell,
  getKeyValue,
  Button,
  Image,
  Chip,
  Avatar,
  Link,
  Select,
  SelectItem,
  Input,
} from "@nextui-org/react";
import { User } from "@/entities/User";
import { capitalize } from "@/utils/base";
import dayjs from "dayjs";
import AppModal from "@/components/modal/appModal";
import { Config } from "@/entities/Config";
import SecretModal from "@/components/modal/secretModal";
import {
  Add,
  AddBoxOutlined,
  AddCircleOutline,
  AddSharp,
  BlockSharp,
  CheckCircleOutline,
} from "@mui/icons-material";
import UserModal from "@/components/modal/userModal";
import ConfigModal from "@/components/modal/configModal/configModal";
import { App } from "@/entities/App";
import ConfirmModal from "@/components/modal/confirmModal";

const ConfigsPage: NextPage = () => {
  const [configs, setConfigs] = useState<Config[]>([]);
  const [visible, setVisible] = useState(false);
  const [env, setEnv] = useState("any");
  const [name, setName] = useState("");
  const [confirmMsg, setConfirmMsg] = useState("");
  const [confirmModalVisible, setConfirmModalVisible] = useState(false);

  const router = useRouter();
  // console.log("🚀 ~ router:", router);
  const appid = router.query.appid as string;

  const { http } = useHttp();
  const [curConfId, setCurConfId] = useState<number>();

  const getConfigList = async (silent = false) => {
    if (!appid) return;
    const res = await http.get(
      "/api/config/list",
      { appid, name, env },
      { isOpenLoading: true, silent }
    );
    if (res?.success) {
      setConfigs(res.data.configs as Config[]);
    }
  };

  const getConfigListRef = useRef(getConfigList);

  useMounted(() => {
    getConfigListRef.current();
  });

  const cols = [
    "id",
    "name",
    "value",
    "type",
    "env",
    "app",
    "introduce",
    "createdAt",
    "creator",
    "editor",
    "disabled",
    "operation",
  ];
  const columns = cols.map((col) => ({
    key: col,
    label:
      col == "disabled" ? "Status" : capitalize(col.replace(/[A-Z]/g, " $&")),
  }));

  const getVal = (item: Config, key: string | number) => {
    // debugger;
    const val = getKeyValue(item, key);
    if (key === "creator" || key === "editor") {
      const user = val as User;
      return (
        <Chip
          size="sm"
          startContent={
            <Avatar
              className="w-4 h-4"
              name={user.name}
              src={user.avatarData}
            />
          }
          color={"success"}
          variant="flat"
        >
          {user.name}
        </Chip>
      );
    } else if (key === "app") {
      const app = val as App;
      return app.name;
    } else if (key === "value") {
      const isBoolean = item.type === "boolean";
      return isBoolean ? (Number(val as string) ? "true" : "false") : val;
    } else if (key === "disabled") {
      const statusVal = val ? "disabled" : "active";
      return (
        <Chip
          size="sm"
          startContent={
            statusVal === "disabled" ? (
              <BlockSharp className="text-md" />
            ) : (
              <CheckCircleOutline className="text-md" />
            )
          }
          color={statusVal === "disabled" ? "warning" : "success"}
          variant="flat"
        >
          {statusVal}
        </Chip>
      );
    } else if (key === "createdAt") {
      const day = dayjs(val).format("YYYY-MM-DD HH:mm:ss");
      return day;
    } else {
      return val;
    }
  };

  const handleChangeStatus = async (disabled: number, configid: number) => {
    const res = await http.post(
      "/api/config/status",
      { disabled, configid, appid },
      { isOpenLoading: true }
    );
    if (res?.success) {
      getConfigListRef.current(true);
    }
  };

  const onConfirm = (success: boolean) => {
    success && getConfigListRef.current(true);
  };

  const handleEdit = (id: number) => {
    setCurConfId(id);
    setVisible(true);
  };

  const handleDel = (item: Config) => {
    setCurConfId(item.id);
    setConfirmMsg(`Delete config "${item.name}"?`);
    setConfirmModalVisible(true);
  };

  const onDelete = async () => {
    const res = await http.post(
      "/api/config/delete",
      { configid: curConfId },
      { isOpenLoading: true }
    );
    if (res?.success) {
      getConfigListRef.current(true);
    }
  };

  const envList = ["any", "all", "local", "development", "test", "production"];

  return (
    <div className="conofigs-page px-6 py-3">
      {true && (
        <ConfigModal
          mode="edit"
          visible={visible}
          closeCallback={() => setVisible(false)}
          configId={curConfId}
          confirmCallback={onConfirm}
        />
      )}

      <ConfirmModal
        title="Confirm"
        message={confirmMsg}
        visible={confirmModalVisible}
        closeCallback={() => setConfirmModalVisible(false)}
        confirmCallback={onDelete}
      />

      <div className="action-bar flex justify-between items-center mb-4">
        <div className="search-section flex-1 flex gap-3 justify-start items-center">
          <label className="mr-2">Filter:</label>
          <div className="name-param">
            <Input
              type="text"
              size="lg"
              value={name}
              className="mr-3"
              onChange={(e) => setName(e.target.value)}
              placeholder="name"
            />
          </div>
          <div className="env-param">
            <Select
              size="sm"
              selectedKeys={[env]}
              onChange={(e) => setEnv(e.target.value)}
              className="w-[250px] mr-3"
              label="Environment"
            >
              {envList.map((item) => (
                <SelectItem key={item} value={item}>
                  {item}
                </SelectItem>
              ))}
            </Select>
          </div>
          <div className="search-action">
            <Button
              variant="solid"
              size="md"
              color="secondary"
              onClick={() => getConfigList(false)}
            >
              Search
            </Button>
          </div>
        </div>
        <div className="right-section text-right flex-0">
          <ConfigModal
            mode="create"
            triggerBtnSize="md"
            confirmCallback={onConfirm}
          />
        </div>
      </div>
      <Table className="text-center" aria-label="apps table">
        <TableHeader columns={columns}>
          {(column) => (
            <TableColumn
              className="text-center"
              align="end"
              allowsResizing
              key={column.key}
            >
              {column.label}
            </TableColumn>
          )}
        </TableHeader>
        <TableBody items={configs} emptyContent="no data">
          {(item) => (
            <TableRow key={item.id}>
              {(columnKey) =>
                columnKey === "operation" ? (
                  <TableCell>
                    <Button
                      variant="flat"
                      className="m-2 rounded-md"
                      size="sm"
                      color="primary"
                      onClick={() => handleEdit(item.id)}
                    >
                      Edit
                    </Button>
                    <Button
                      variant="flat"
                      className="m-2 rounded-md"
                      size="sm"
                      color="danger"
                      onClick={() => handleDel(item)}
                    >
                      Del
                    </Button>
                    {!item.disabled ? (
                      <Button
                        variant="flat"
                        className="m-2 rounded-md"
                        size="sm"
                        color="danger"
                        onClick={() => handleChangeStatus(1, item.id)}
                      >
                        Disable
                      </Button>
                    ) : (
                      <Button
                        variant="flat"
                        className="m-2 rounded-md"
                        size="sm"
                        color="danger"
                        onClick={() => handleChangeStatus(0, item.id)}
                      >
                        Enable
                      </Button>
                    )}
                  </TableCell>
                ) : (
                  <TableCell>{getVal(item, columnKey)}</TableCell>
                )
              }
            </TableRow>
          )}
        </TableBody>
      </Table>
    </div>
  );
};

export { getServerSideProps };

export default withAuth(ConfigsPage);
